home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / tutorials / geometer / ui.c < prev   
Encoding:
C/C++ Source or Header  |  1994-08-02  |  25.2 KB  |  1,134 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17.  
  18. #include "parse.h"
  19. #include <gl.h>
  20. #include <device.h>
  21. #include <math.h>
  22. #include <stream.h>
  23. //#include "gizmo.h"
  24. #include <osfcn.h>
  25. #include "showcaseui.h"
  26. #include <strings.h>
  27. #include "generic.h"
  28. #include "cmds.h"
  29.  
  30. #define BUTTONHEIGHT 16
  31. #define LINETYPECOUNT 3
  32.  
  33. extern void     showcomment();
  34. long    currentcolor = WHITE;
  35. extern long     showinfo;
  36. void            drawcolorpalette();
  37. long            printall(char *);
  38. void            describeprimitive(primitive *);
  39. extern void     restore255();
  40. extern void     moveworld(long, long);
  41. extern void     zoomworld(float);
  42.         
  43. struct butblock {
  44.     long xmin, ymin, xmax, ymax;
  45.     char *title;
  46.     long cmd;
  47.     Button *b;
  48. } vertblock[] = {
  49.     { 10, 5, 0, 100, "New Vert", MOUSEVERT, 0 },
  50.     { 10, 6, 0, 100, "L,L=>V", LLVERT, 0 },
  51.     { 10, 7, 0, 100, "V,V=>Vmid", VVMID, 0 }, 
  52.     { 10, 8, 0, 100, "V on L", VLCONSTRAIN, 0 },
  53.     { 10, 9, 0, 100, "V on C", VONCIRC, 0 }, 
  54.     { 10, 10, 0, 100, "L,C=>V", LCV1, 0 }, 
  55.     { 10, 12, 0, 100, "C,C=>V", CCV1, 0 }, 
  56.     { 0,0,0,0,0,0,0 }
  57. };
  58.  
  59. butblock conicblock[] = {
  60.     { 10, 1, 150, 250, "5*V=>Con", C5V, 0 }, 
  61.     { 0,0,0,0,0,0,0 }
  62. };
  63.  
  64. butblock lineblock[] = {
  65.     { 120, 5, 0, 100, "V,V=>L", VVLINE },
  66.     { 120, 6, 0, 100, "V,L=>Lprp", VLLINEPERP },
  67.     { 120, 7, 0, 100, "V,L=>Lpar", VLLINEPAR }, 
  68.     { 120, 8, 0, 100, "V,C=>L", VCL1}, 
  69.     { 120, 10, 0, 100, "C,C=>Lext", CCLE1}, 
  70.     { 120, 11, 0, 100, "C,C=>Lint", CCLI1}, 
  71.     { 0,0,0,0,0,0,0 }
  72. };
  73.  
  74. butblock layerblock1[] = {
  75.     { 10, 1, 0, 0, "0", L0 }, 
  76.     { 10, 2, 0, 0, "4", L4 }, 
  77.     { 10, 3, 0, 0, "8", L8 }, 
  78.     { 10, 4, 0, 0, "12", L12 }, 
  79.     { 0,0,0,0,0,0,0 }
  80. };
  81.  
  82. butblock layerblock2[] = {
  83.     { 10, 1, 0, 0, "1", L1 }, 
  84.     { 10, 2, 0, 0, "5", L5 }, 
  85.     { 10, 3, 0, 0, "9", L9 }, 
  86.     { 10, 4, 0, 0, "13", L13 }, 
  87.     { 0,0,0,0,0,0,0 }
  88. };
  89.  
  90. butblock layerblock3[] = {
  91.     { 10, 1, 0, 0, "2", L2 }, 
  92.     { 10, 2, 0, 0, "6", L6 }, 
  93.     { 10, 3, 0, 0, "10", L10 }, 
  94.     { 10, 4, 0, 0, "14", L14 }, 
  95.     { 0,0,0,0,0,0,0 }
  96. };
  97.  
  98. butblock layerblock4[] = {
  99.     { 10, 1, 0, 0, "3", L3 }, 
  100.     { 10, 2, 0, 0, "7", L7 }, 
  101.     { 10, 3, 0, 0, "11", L11 }, 
  102.     { 10, 4, 0, 0, "15", L15 }, 
  103.     { 0,0,0,0,0,0,0 }
  104. };
  105.  
  106. butblock layerblock5[] = {
  107.     { 10, 1, 0, 0, "on", LON }, 
  108.     { 10, 2, 0, 0, "start", LSTART }, 
  109.     { 10, 3, 0, 0, "next", LNEXT }, 
  110.     { 10, 4, 0, 0, "prev", LPREV }, 
  111.     { 0,0,0,0,0,0,0 }
  112. };
  113.  
  114. butblock circblock[] = {
  115.     { 10, 16, 0, 100, "Ctr,Edg=>C", MAKECIRC },
  116.     { 10, 17, 0, 100, "V,V,V=>C", VVVC }, 
  117.     { 0,0,0,0,0,0,0 }
  118. };
  119.  
  120. butblock otherblock[] = {
  121.     { 120, 24, 0, 100, "Set Color",  COLORCMD }, 
  122.     { 0,0,0,0,0,0,0 }
  123. };
  124.  
  125. void initblock(long xmin, long ymin, butblock *bblk)
  126. {
  127.     long blockcount = 0;
  128.     while (bblk[blockcount].title) blockcount++;
  129.     for (long i = 0; i < blockcount; i++) {
  130.     bblk[i].b = newtinyradio(xmin+xsize-UIWIDTH, ymin+16*(blockcount-i));
  131.     loadbut(bblk[i].b, bblk[i].title);
  132.     }
  133. }
  134.  
  135. long layerset = 0xffffffff;
  136.  
  137. static void setlayerbuttons()
  138. {
  139.     drawgeom(); drawgeom();
  140.     for (long i = 0; i < 16; i++) {
  141.     Button *b;
  142.     switch (i & 3) {
  143.         case 0:
  144.             b = layerblock1[i>>2].b;
  145.         break;
  146.         case 1:
  147.             b = layerblock2[i>>2].b;
  148.         break;
  149.         case 2:
  150.             b = layerblock3[i>>2].b;
  151.         break;
  152.         case 3:
  153.             b = layerblock4[i>>2].b;
  154.         break;
  155.     }
  156.     if (layerset & (1<<i))
  157.         activatebut(b);
  158.     else
  159.         deactivatebut(b);
  160.         drawbut(b); swapbuffers(); drawbut(b);
  161.     }
  162. }
  163.  
  164. void deleteblockbuttons(butblock *bblk)
  165. {
  166.     while (bblk->title) { freebut(bblk->b); bblk++; }
  167. }
  168.  
  169. void drawblock(butblock *bblk)
  170. {
  171.     while (bblk->title) {
  172.         drawbut(bblk->b);
  173.     bblk++;
  174.     }
  175. }
  176.  
  177. void linkbuts(Button *b, butblock *bblk)
  178. {
  179.     while (bblk->title) { linkbuttons(b, bblk->b); bblk++; }
  180. }
  181.  
  182. void linkradiobuttons()
  183. {
  184.     Button *b = vertblock[0].b;
  185.     linkbuts(b, vertblock);
  186.     linkbuts(b, lineblock);
  187.     linkbuts(b, circblock);
  188.     linkbuts(b, conicblock);
  189.     linkbuts(b, otherblock);
  190. }
  191.  
  192. void turnoffradio()
  193. {
  194.     Button *b = vertblock[0].b;
  195.     viewport((short)0, (short)(xsize-1), 0, (short)(ysize-PULLDOWNHEIGHT-1));
  196.     ortho2(-0.5, xsize-0.5, -0.5, ysize-PULLDOWNHEIGHT-0.5);
  197.     unpresslinkbuts(b);
  198.     //drawui();
  199. }
  200.  
  201. struct labellist {
  202.     long x, y;
  203.     char *s;
  204. } titles[] = {
  205.     {0, 0, "New Vertex"},
  206.     {0, 0, "New Line"},
  207.     {0, 0, "New Circle"},
  208.     {0, 0, "    Other"},
  209.     {0, 0, "Line Type"},
  210.     {0, 0, "Layer Control"},
  211.     {0, 0, "New Conic"}, 
  212.     {0, 0, 0}
  213. };
  214.  
  215. void initlabel(long labelnumber, long xmin, long ymin)
  216. {
  217.     titles[labelnumber].x = xmin+xsize-UIWIDTH;
  218.     titles[labelnumber].y = ymin;
  219. }
  220.  
  221. void drawlabels()
  222. {
  223.     long i=0;
  224.     while (titles[i].s) {
  225.         drawboldlabel(titles[i].s, titles[i].x, titles[i].y);
  226.     i++;
  227.     }
  228. }
  229.  
  230. struct linetypes {
  231.     char *s;
  232.     long cmd;
  233.     Button *b;
  234. } lt[] = {
  235.     { "Line", MAKELONGLINE }, 
  236.     { "Ray", MAKERAY }, 
  237.     { "Segment", MAKESEGMENT }
  238. };
  239.  
  240. void initlinetypes(long xmin, long ymin)
  241. {
  242.     for (long i = 0; i < LINETYPECOUNT; i++) {
  243.     lt[i].b = newradiobut(xmin+xsize-UIWIDTH, ymin + 25*(LINETYPECOUNT-1-i));
  244.     loadbut(lt[i].b, lt[i].s);
  245.     }
  246.     linkbuttons(lt[0].b, lt[1].b);
  247.     linkbuttons(lt[1].b, lt[2].b);
  248.     switch(currentlinetype) {
  249.     case _longline:
  250.         activatebut(lt[0].b); break;
  251.     case _ray12:
  252.         activatebut(lt[1].b); break;
  253.     case _segment:
  254.         activatebut(lt[2].b); break;
  255.     }
  256. }
  257.  
  258. void drawlinetypes()
  259. {
  260.     for (long i = 0; i < LINETYPECOUNT; i++)
  261.         drawbut(lt[i].b);
  262. }
  263.  
  264. Button *showinvis, *Showinfo;
  265. TextBox *tb;
  266.  
  267. void deleteallbuts()
  268. {
  269.     deleteblockbuttons(vertblock);
  270.     deleteblockbuttons(lineblock);
  271.     deleteblockbuttons(conicblock);
  272.     deleteblockbuttons(circblock);
  273.     deleteblockbuttons(otherblock);
  274.     deleteblockbuttons(layerblock1);
  275.     deleteblockbuttons(layerblock2);
  276.     deleteblockbuttons(layerblock3);
  277.     deleteblockbuttons(layerblock4);
  278.     deleteblockbuttons(layerblock5);
  279.     for (long i = 0; i < LINETYPECOUNT; i++)
  280.         freebut(lt[i].b);
  281.     freebut(showinvis);
  282. }
  283.  
  284. void initinvisible(long xmin, long ymin)
  285. {
  286.     showinvis = newcheckbut(xmin+xsize-UIWIDTH, ymin);
  287.     loadbut(showinvis, "Show Invis");
  288.     if (showinvisible) activatebut(showinvis);
  289.     Showinfo = newcheckbut(xmin+xsize-UIWIDTH, ymin - 25);
  290.     loadbut(Showinfo, "Show Info");
  291.     if (showinfo) activatebut(Showinfo);
  292. }
  293.  
  294. void drawinvisible()
  295. {
  296.     drawbut(showinvis);
  297.     drawbut(Showinfo);
  298. }
  299.  
  300. long Cxmin=10, Cwidth = 23, Cymin = 10, Cheight = 33;
  301. extern long uiinited;
  302.  
  303. void initshowcaseui()
  304. {
  305.     if (uiinited == 0) {
  306.     initui();
  307.     initbut();
  308.     inittb();
  309.     uiinited = 1;
  310.     }
  311.     if (tb == 0)
  312.         tb = newtb(xsize-UIWIDTH+10, xsize-10, 450);
  313.     layerset = 0x1;
  314.     initlabel(0, 20, 388);
  315.     initblock(10, 252, vertblock);
  316.     initlabel(1, 20, 220);
  317.     initblock(10, 101, lineblock);
  318.     initlabel(2, 20, 86);
  319.     initblock(120, 187, conicblock);
  320.     initlabel(6, 130, 226);
  321.     initblock(10, 30, circblock);
  322.     initlabel(3, 20, 30);
  323.     initblock(10, -10, otherblock);
  324.     initblock(10, 470, layerblock1);
  325.     initblock(50, 470, layerblock2);
  326.     initblock(90, 470, layerblock3);
  327.     initblock(130, 470, layerblock4);
  328.     initblock(170, 470, layerblock5);
  329.     initlabel(5, 50, 560);
  330.     initlinetypes(120, 305);
  331.     initlabel(4, 120, 388);
  332.     initinvisible(120, 275);
  333.     linkradiobuttons();
  334.     movetb(tb, xsize-UIWIDTH+10, xsize-10, 450);
  335.     loadtb(tb, "Basic Mode");
  336.     Cxmin = xsize-UIWIDTH+10;
  337.     Cymin = 410;
  338. }
  339.  
  340. void drawshowcaseui()
  341. {
  342.     scrmask((short)(xsize-UIWIDTH), (short)(xsize-1), 0, (short)(ysize-1));
  343.     backgroundclear();
  344.     scrmask(0, (short)(xsize-1), 0, (short)(ysize-1));
  345.     drawblock(vertblock);
  346.     drawblock(lineblock);
  347.     drawblock(conicblock);
  348.     drawblock(circblock);
  349.     drawblock(layerblock1);
  350.     drawblock(layerblock2);
  351.     drawblock(layerblock3);
  352.     drawblock(layerblock4);
  353.     drawblock(layerblock5);
  354.     drawblock(otherblock);
  355.     drawlabels();
  356.     drawlinetypes();
  357.     drawinvisible();
  358.     drawcolorpalette();
  359.     drawtb(tb);
  360. }
  361.  
  362. void showmessage(char *s)
  363. {
  364.     viewport((short)0, (short)(xsize-1), 0, (short)(ysize-PULLDOWNHEIGHT-1));
  365.     ortho2(-0.5, xsize-0.5, -0.5, ysize-PULLDOWNHEIGHT-0.5);
  366.     loadtb(tb, s);
  367.     frontbuffer(1);
  368.     drawtb(tb);
  369.     frontbuffer(0);
  370. }
  371.  
  372. long testblock(butblock *bblk, long x, long y)
  373. {
  374.     while (bblk->title) {
  375.         if (inbut(bblk->b, x, y)) {
  376.         /*if (pressbut(bblk->b, x, y))*/
  377.             activatebut(bblk->b);
  378.         drawbut(bblk->b); swapbuffers(); drawbut(bblk->b);
  379.             return bblk->cmd;
  380.         /*return 0;*/
  381.     }
  382.     bblk++;
  383.     }
  384.     return 0;
  385. }
  386.  
  387. long testlinetypes(long x, long y)
  388. {
  389.     for (long i = 0; i < LINETYPECOUNT; i++) {
  390.     if (selectedpressbut(lt[i].b, x, y, 1))
  391.         return lt[i].cmd;
  392.     }
  393.     return 0;
  394. }
  395.  
  396. long testinvisible(long x, long y)
  397. {
  398.     if (inbut(showinvis, x, y)) {
  399.     if (pressbut(showinvis, x, y))
  400.         return INVIS;
  401.     }
  402.     if (inbut(Showinfo, x, y)) {
  403.     if (pressbut(Showinfo, x, y))
  404.         return INFO;
  405.     }
  406.     return 0;
  407. }
  408.  
  409. long testshowcase(long x, long y)
  410. {
  411.     long result;
  412.     viewport((short)0, (short)(xsize-1), 0, (short)(ysize-PULLDOWNHEIGHT-1));
  413.     ortho2(-0.5, xsize-0.5, -0.5, ysize-PULLDOWNHEIGHT-0.5);
  414.     if (result = testblock(vertblock, x, y)) return result;
  415.     if (result = testblock(circblock, x, y)) return result;
  416.     if (result = testblock(conicblock, x, y)) return result;
  417.     if (result = testblock(otherblock, x, y)) return result;
  418.     if (result = testblock(layerblock1, x, y)) return result;
  419.     if (result = testblock(layerblock2, x, y)) return result;
  420.     if (result = testblock(layerblock3, x, y)) return result;
  421.     if (result = testblock(layerblock4, x, y)) return result;
  422.     if (result = testblock(layerblock5, x, y)) return result;
  423.     return testblock(lineblock, x, y);
  424. }
  425.  
  426. void locatem(long x, long y)
  427. {
  428.     for (long i = 0; i < LINETYPECOUNT; i++)
  429.         locatebut(lt[i].b, x, y);
  430.     locatebut(showinvis, x, y);
  431.     locatebut(Showinfo, x, y);
  432. }
  433.  
  434. // User interface state:
  435.  
  436. enum uistate {
  437.     SELECTSTATE, VV1STATE, VV2STATE, LL1STATE, LL2STATE, 
  438.     VL1STATE, LPERP1STATE, LPERP2STATE, 
  439.     LPAR1STATE, LPAR2STATE, CREATEVERTEXSTATE, 
  440.     C1STATE, C2STATE, VVMID1STATE, VVMID2STATE, 
  441.     VONCIRC1STATE, LCV11, LCV12,  
  442.     VCL11, VCL12, LCCEXT11, LCCEXT12, 
  443.     LCCINT11, LCCINT12, VCC11, VCC12, CVVV1, 
  444.     CVVV2, CVVV3, SETCOLORS, 
  445.     C5V1, C5V2, C5V3, C5V4, C5V5, 
  446. } UIstate;
  447.  
  448. long sticky = 0;
  449. extern long vnumber;
  450.  
  451. void setselect()
  452. {
  453.     if (UIstate != SELECTSTATE) {
  454.         turnoffradio();
  455.     drawui();
  456.     UIstate = SELECTSTATE;
  457.     }
  458. }
  459.  
  460. void drawcolorpalette()
  461. {
  462.     for (long i = 0; i < 9; i++) {
  463.     if (i < 7)
  464.         color((short)(i+1));
  465.     else
  466.         color(8);
  467.     rectfi(Cxmin + i*Cwidth, Cymin,
  468.         Cxmin + (i+1)*Cwidth, Cymin + Cheight);
  469.     color(BLACK);
  470.     recti(Cxmin + i*Cwidth, Cymin,
  471.         Cxmin + (i+1)*Cwidth, Cymin + Cheight);
  472.     }
  473.     drawlabel("In", 7*Cwidth+Cxmin+6, Cymin+15);
  474.     drawlabel("Sm", 8*Cwidth+Cxmin+2, Cymin+15);
  475. }
  476.  
  477. long incolor(long x, long y)
  478. {
  479.     long col;
  480.     
  481.     if (x < Cxmin || x > Cxmin+9*Cwidth ||
  482.         y < Cymin || y > Cymin+Cheight) return 0;
  483.     col = (x-Cxmin)/Cwidth+1;
  484.     if (col == 8) col = C_1;
  485.     if (col == 9) col = C_2;
  486.     return col;
  487. }
  488.  
  489. void clearbuffer()
  490. {
  491.     vnumber = 1;
  492.     cleartable(idtable);
  493.     clearplist();
  494.     setselect();
  495.     drawmode(PUPDRAW); color(0); clear(); drawmode(NORMALDRAW);
  496. }
  497.  
  498. void displaymessage(char *s)
  499. {
  500.     message(s, "Confirm", 0, 0);
  501. #ifdef NOTDEF
  502.     long w = winget();
  503.     prefposition(100, 700, 100, 200);
  504.     long w1 = winopen("message");
  505.     color(WHITE);
  506.     clear();
  507.     color(BLACK);
  508.     cmov2i(20, 50);
  509.     charstr(s);
  510.     cmov2i(30, 20);
  511.     charstr("Press <ESC> to continue");
  512.     while (getbutton(ESCKEY)==0) sginap(1);
  513.     winclose(w1);
  514.     winset(w);
  515. #endif
  516. }
  517.  
  518. void drawui()
  519. {
  520.     viewport((short)0, (short)(xsize-1), 0, (short)(ysize-PULLDOWNHEIGHT-1));
  521.     ortho2(-0.5, xsize-0.5, -0.5, ysize-PULLDOWNHEIGHT-0.5);
  522.     drawgeom();
  523.     drawshowcaseui();
  524.     swapbuffers();
  525.     drawshowcaseui();
  526. }
  527.  
  528. void checklinetype()
  529. {
  530.     if (pselected && pselected->ptype == _line) {
  531.         line *l = (line *)pselected;
  532.     l->type = currentlinetype;
  533.     // XXX setlinetype(l, currentlinetype);
  534.     }
  535. }
  536.  
  537. void editgeomtext()
  538. {
  539.     FILE *fp = 0;
  540.     printall("/tmp/geom.x");
  541.     do {
  542.         if (fp) fclose(fp);
  543.         system("jot -f /tmp/geom.x");
  544.         fp = fopen("/tmp/geom.x", "r");
  545.     cleartable(idtable);
  546.     clearplist();
  547.     } while (0 == parsefile(fp));
  548.     fclose(fp);
  549. }
  550.  
  551. char dir[200];
  552.  
  553. long interpbutton(long x, long y)
  554. {
  555.     long command;
  556.  
  557.     command = testshowcase(x, y);
  558.     if (command == 0) command = testlinetypes(x, y);
  559.     if (command == 0) command = testinvisible(x, y);
  560.     drawui();
  561.     long c;
  562.     if (c = incolor(x, y)) {
  563.     setselect();
  564.     if (c == C_1 || c == C_2) return c;
  565.         return C0 + c;
  566.     }
  567.     return command;
  568. }
  569.  
  570. void setmessage()
  571. {
  572.     char *msg = 0;
  573.     static char *omsg = 0;
  574.  
  575.     switch (UIstate) {
  576.     case SELECTSTATE:
  577.         msg = "Basic Mode"; break;
  578.     case VV1STATE:
  579.     case CVVV1:
  580.     case C5V1:
  581.     case VVMID1STATE:
  582.         msg = "Pick Vertex 1"; break;
  583.     case VV2STATE:
  584.     case CVVV2:
  585.     case C5V2:
  586.     case VVMID2STATE:
  587.         msg = "Pick Vertex 2"; break;
  588.     case LL1STATE:
  589.         msg = "Pick Line 1"; break;
  590.     case LL2STATE:
  591.         msg = "Pick Line 2"; break;
  592.     case VL1STATE:
  593.         msg = "New Vertex on Line"; break;
  594.     case LPERP1STATE:
  595.     case LPAR1STATE:
  596.     case VCL11:
  597.         msg = "Pick Vertex"; break;
  598.     case LPERP2STATE:
  599.         msg = "Pick Perpendicular Line"; break;
  600.     case LPAR2STATE:
  601.         msg = "Pick Parallel Line"; break;
  602.     case CREATEVERTEXSTATE:
  603.         msg = "Make New Vertex"; break;
  604.     case C1STATE:
  605.         msg = "Circle Center Vertex"; break;
  606.     case C2STATE:
  607.         msg = "Circle Edge Vertex"; break;
  608.     case VONCIRC1STATE:
  609.         msg = "New Vertex on Circle"; break;
  610.     case LCV11:
  611.         msg = "Pick Line"; break;
  612.     case VCL12:
  613.     case LCV12:
  614.         msg = "Pick Circle"; break;
  615.     case VCC11:
  616.     case LCCEXT11:
  617.     case LCCINT11:
  618.         msg = "Pick Circle 1"; break;
  619.     case VCC12:
  620.     case LCCEXT12:
  621.     case LCCINT12:
  622.         msg = "Pick Circle 2"; break;
  623.     case CVVV3:
  624.     case C5V3:
  625.         msg = "Pick Vertex 3"; break;
  626.     case C5V4:
  627.         msg = "Pick Vertex 4"; break;
  628.     case C5V5:
  629.         msg = "Pick Vertex 5"; break;
  630.     case SETCOLORS:
  631.         msg = "Pick Item to Color"; break;
  632.     }
  633.     if (omsg != msg) {
  634.         showmessage(msg);
  635.     omsg = msg;
  636.     }
  637. }
  638.  
  639. void dispatchcmd(long, long);
  640. long cookedqread(long *);
  641. void handleredraw();
  642. void handlegeombutton(long x, long y);
  643. extern long EPS;
  644.  
  645. /* mainloop() is the main loop of the program that collects commands
  646.  * and dispatches to the correct routines.  In this application, commands
  647.  * come from the pull-down menu only.
  648.  */
  649.  
  650. void mainloop()
  651. {
  652.     long cmd = -1;
  653.     long val, dev, x, y, xx, xpos, ypos, ly;
  654.     short junkval;
  655.     
  656.     handleredraw();
  657.     setlayerbuttons();
  658.     UIstate = SELECTSTATE;
  659.     while (1) {
  660.         dev = cookedqread(&val);
  661.     setmessage();
  662.     if (dev == LEFTMOUSE || dev == MIDDLEMOUSE) {
  663.         if (val == 1 && dev == LEFTMOUSE)
  664.             cmd = pulldownevent(getvaluator(MOUSEX)-xorg, getvaluator(MOUSEY)-yorg);
  665.             if (cmd != -1) {dev = cmd; val = 0; cmd = -1; }
  666.         else {
  667.         if (val == 0) continue;
  668.         x = getvaluator(MOUSEX);
  669.         y = getvaluator(MOUSEY);
  670.         if (x - xorg > xsize-UIWIDTH) {
  671.             if (xx = interpbutton(x-xorg, y-yorg)) {
  672.             sticky = (dev == MIDDLEMOUSE) ? 1 : 0;
  673.             } else
  674.             sticky = 0;
  675.             dev = xx;
  676.             if (dev == 0) setselect();
  677.         }
  678.         }
  679.         if (dev == LEFTMOUSE || dev == RIGHTMOUSE) {
  680.         handlegeombutton(x, y);
  681.         drawgeom();
  682.         continue;
  683.         }
  684.     }
  685.     if (dev == MOUSEX || dev == MOUSEY) {
  686.         while (qtest() == MOUSEX || qtest() == MOUSEY) dev = qread(&junkval);
  687.         xpos = getvaluator(MOUSEX)-xorg;
  688.         ypos = getvaluator(MOUSEY)-yorg;
  689.         if (xpos > xsize-UIWIDTH && xpos < xsize &&
  690.         ypos > 0 && ypos < ysize) {
  691.             locatem(xpos, ypos);
  692.         }
  693.         continue;
  694.     }
  695.     switch (dev) {
  696.         case MAKELONGLINE:
  697.         currentlinetype = _longline;
  698.         checklinetype();
  699.             break;
  700.         case MAKESEGMENT:
  701.         currentlinetype = _segment;
  702.         checklinetype();
  703.             break;
  704.         case MAKERAY:
  705.         currentlinetype = _ray12;
  706.         checklinetype();
  707.             break;
  708.         case MOUSEVERT:
  709.             UIstate = CREATEVERTEXSTATE;
  710.         break;
  711.         case VVLINE:
  712.         UIstate = VV1STATE;
  713.         break;
  714.         case LLVERT:
  715.             UIstate = LL1STATE;
  716.         break;
  717.         case VLLINEPERP:
  718.             UIstate = LPERP1STATE;
  719.         break;
  720.         case VLLINEPAR:
  721.             UIstate = LPAR1STATE;
  722.         break;
  723.         case VLCONSTRAIN:
  724.             UIstate = VL1STATE;
  725.         break;
  726.         case MAKECIRC:
  727.             UIstate = C1STATE;
  728.         break;
  729.         case VVMID:
  730.             UIstate = VVMID1STATE;
  731.         break;
  732.         case VONCIRC:
  733.             UIstate = VONCIRC1STATE;
  734.         break;
  735.         case INVIS:
  736.             showinvisible = 1 - showinvisible;
  737.         break;
  738.         case INFO:
  739.             showinfo = 1 - showinfo;
  740.         break;
  741.         case LCV1:
  742.             UIstate = LCV11;
  743.         break;
  744.         case VCL1:
  745.             UIstate = VCL11;
  746.         break;
  747.         case CCLE1:
  748.             UIstate = LCCEXT11;
  749.         break;
  750.         case CCLI1:
  751.             UIstate = LCCINT11;
  752.         break;
  753.         case CCV1:
  754.             UIstate = VCC11;
  755.         break;
  756.         case VVVC:
  757.             UIstate = CVVV1;
  758.         break;
  759.         case C5V:
  760.             UIstate = C5V1;
  761.         break;
  762.         case COLORCMD:
  763.             UIstate = SETCOLORS;
  764.         break;
  765.         case COMCMD:
  766.             showcomment();
  767.         break;
  768.         case LON:
  769.             layerset = 0xffffffff;
  770.         setlayerbuttons();
  771.         deactivatebut(layerblock5[0].b);
  772.         drawbut(layerblock5[0].b); swapbuffers(); drawbut(layerblock5[0].b);
  773.         break;
  774.         case LPREV:
  775.             layerset >>= 1;
  776.         setlayerbuttons();
  777.         deactivatebut(layerblock5[3].b);
  778.         drawbut(layerblock5[3].b); swapbuffers(); drawbut(layerblock5[3].b);
  779.         break;
  780.         case LNEXT:
  781.             layerset <<= 1;
  782.         setlayerbuttons();
  783.         deactivatebut(layerblock5[2].b);
  784.         drawbut(layerblock5[2].b); swapbuffers(); drawbut(layerblock5[2].b);
  785.         break;
  786.         case LSTART:
  787.             layerset = 0x1;
  788.         setlayerbuttons();
  789.         deactivatebut(layerblock5[1].b);
  790.         drawbut(layerblock5[1].b); swapbuffers(); drawbut(layerblock5[1].b);
  791.         break;
  792.         case L0: case L1: case L2: case L3: case L4: case L5:
  793.         case L6: case L7: case L8: case L9: case L10: case L11:
  794.         case L12: case L13: case L14: case L15:
  795.             ly = dev - L0;
  796.         layerset ^= (1<<ly);
  797.         setlayerbuttons();
  798.             break;
  799.         case C_1: case C_2: case C_3:
  800.         case C0: case C1: case C2: case C3:
  801.         case C4: case C5: case C6: case C7:
  802.         currentcolor = (short)(dev - C0);
  803.         if (pselected) {
  804.             setdirtyfile();
  805.             pselected->Color = currentcolor;
  806.         }
  807.         break;
  808.         case QUITDAMMIT: // quit, dammit!
  809.         dirtyfile_flag = 0;
  810.         handlequitcmd();
  811.         break;
  812.         case NEWCMD:
  813.         setselect();
  814.         handlenewcmd();
  815.         break;
  816.         case OPENCMD:
  817.         setselect();
  818.         handleopencmd();
  819.         break;
  820.         case SAVECMD:
  821.         setselect();
  822.         handlesavecmd();
  823.         break;
  824.         case SAVEASCMD:
  825.         setselect();
  826.         handlesaveascmd();
  827.         break;
  828.         case INSERTCMD:
  829.         setselect();
  830.         handleinsertcmd();
  831.         break;
  832.         case PRINTCMD:
  833.         EPS = 0;
  834.         handleprintcmd();
  835.         setselect();
  836.         break;
  837.         case PRINTEPS:
  838.         EPS = 1;
  839.         handleprintcmd();
  840.         setselect();
  841.         break;
  842.         case QUITCMD:
  843.         setselect();
  844.         handlequitcmd();
  845.         break;
  846.         case HELPCMD:
  847.         setselect();
  848.         handlehelpcmd();
  849.         break;
  850.         case LEFTARROWKEY:
  851.         if (val == 0) break;
  852.         moveworld(-1, 0);
  853.         break;
  854.         case RIGHTARROWKEY:
  855.         if (val == 0) break;
  856.         moveworld(1, 0);
  857.         break;
  858.         case UPARROWKEY:
  859.         if (val == 0) break;
  860.         moveworld(0, 1);
  861.         break;
  862.         case DOWNARROWKEY:
  863.         if (val == 0) break;
  864.         moveworld(0, -1);
  865.         break;
  866.         case PAGEUPKEY:
  867.         if (val == 0) break;
  868.         zoomworld(1.01);
  869.         break;
  870.         case PAGEDOWNKEY:
  871.         if (val == 0) break;
  872.         zoomworld(1.0/1.01);
  873.         break;
  874.         case EDITGEOM:
  875.         editgeomtext();
  876.         sticky = 0;
  877.         setselect();
  878.         break;
  879.         case DELSELECTION:
  880.         if (pselected)
  881.             deleteprimitive(pselected);
  882.         break;
  883.         case DESCRIBESELN:
  884.         if (pselected)
  885.             describeprimitive(pselected);
  886.         break;
  887.         case WINQUIT:
  888.         case WINSHUT:
  889.             handlequitcmd();
  890.         break;
  891.         case REDRAW:
  892.             handleredraw();
  893.         break;
  894.         case 0:
  895.         break;
  896.         default:
  897.         break;
  898.     }
  899.         drawgeom();
  900.     }
  901. }
  902.  
  903. void handlegeombutton(long x, long y)
  904. {
  905.     float fx, fy;
  906.     static vertex *v1, *v2, *v3, *v4, *v5;
  907.     static line *l1, *l2;
  908.     static circle *c1, *c2;
  909.     primitive *p;
  910.  
  911.     getpoint(&fx, &fy, x, y);
  912.     switch (UIstate) {
  913.     case SELECTSTATE:
  914.         selectvertex(fx, fy);
  915.         break;
  916.     case CREATEVERTEXSTATE:
  917.         v1 = makevertex(fx, fy);
  918.         v1->c.type = VERTFREE;
  919.         if (!sticky) setselect();
  920.         addprimitive(v1);
  921.         break;
  922.     case VV1STATE:
  923.         v1 = hitvertex(fx, fy);
  924.         if (v1)
  925.         UIstate = VV2STATE;
  926.         break;
  927.     case VV2STATE:
  928.         v2 = hitvertex(fx, fy);
  929.         if (v2) {
  930.             if (sticky) UIstate = VV1STATE; else setselect();
  931.         addprimitive(linevertvert(v1, v2));
  932.         }
  933.         break;
  934.     case C1STATE:
  935.         v1 = hitvertex(fx, fy);
  936.         if (v1)
  937.         UIstate = C2STATE;
  938.         break;
  939.     case C2STATE:
  940.         v2 = hitvertex(fx, fy);
  941.         if (v2) {
  942.             if (sticky) UIstate = C1STATE; else setselect();
  943.         addprimitive(circvertvert(v1, v2));
  944.         }
  945.         break;
  946.     case VVMID1STATE:
  947.         v1 = hitvertex(fx, fy);
  948.         if (v1)
  949.         UIstate = VVMID2STATE;
  950.         break;
  951.     case VVMID2STATE:
  952.         v2 = hitvertex(fx, fy);
  953.         if (v2) {
  954.             if (sticky) UIstate = VVMID1STATE; else setselect();
  955.         addprimitive(vertvertvertmid(v1, v2));
  956.         }
  957.         break;
  958.     case LL1STATE:
  959.         l1 = hitline(fx, fy);
  960.         if (l1)
  961.         UIstate = LL2STATE;
  962.         break;
  963.     case LL2STATE:
  964.         l2 = hitanotherline(fx, fy, l1);
  965.         if (l2) {
  966.             if (sticky) UIstate = LL1STATE; else setselect();
  967.         addprimitive(vertlineline(l1, l2));
  968.         }
  969.         break;
  970.     case VL1STATE:
  971.         l1 = hitline(fx, fy);
  972.         if (l1) {
  973.         vertex *v1 = new vertex;
  974.         genname(v1);
  975.         v1->xw = fx; v1->yw = fy; v1->w = 1.0;
  976.         pselected = v1;
  977.         v1->c.type = VERTFREE;
  978.             if (sticky) UIstate = VL1STATE; else setselect();
  979.         addprimitive(v1);
  980.         verttoline(v1, l1);
  981.         }
  982.         break;
  983.     case VONCIRC1STATE:
  984.         c1 = hitcircle(fx, fy);
  985.         if (c1) {
  986.         vertex *v1 = new vertex;
  987.         genname(v1);
  988.         v1->xw = fx; v1->yw = fy; v1->w = 1.0;
  989.         pselected = v1;
  990.         v1->c.type = VERTFREE;
  991.             if (sticky) UIstate = VONCIRC1STATE; else setselect();
  992.         addprimitive(v1);
  993.         verttocirc(v1, c1);
  994.         }
  995.         break;
  996.     case LCV11:
  997.         l1 = hitline(fx, fy);
  998.         if (l1)
  999.         UIstate = LCV12;
  1000.         break;
  1001.     case LCV12:
  1002.         c1 = hitcircle(fx, fy);
  1003.         if (c1) {
  1004.             if (sticky) UIstate = LCV11; else setselect();
  1005.         addprimitive(linecirctovert1(l1, c1, fx, fy));
  1006.         }
  1007.         break;
  1008.     case VCL11:
  1009.         v1 = hitvertex(fx, fy);
  1010.         if (v1)
  1011.         UIstate = VCL12;
  1012.         break;
  1013.     case VCL12:
  1014.         c1 = hitcircle(fx, fy);
  1015.         if (c1) {
  1016.             if (sticky) UIstate = VCL11; else setselect();
  1017.         addprimitive(vertcirctoline1(v1, c1, fx, fy));
  1018.         }
  1019.         break;
  1020.     case LPERP1STATE:
  1021.         v1 = hitvertex(fx, fy);
  1022.         if (v1)
  1023.         UIstate = LPERP2STATE;
  1024.         break;
  1025.     case LPERP2STATE:
  1026.         l1 = hitline(fx, fy);
  1027.         if (l1) {
  1028.             if (sticky) UIstate = LPERP1STATE; else setselect();
  1029.         addprimitive(linevertlineperp(v1, l1));
  1030.         }
  1031.         break;
  1032.     case LPAR1STATE:
  1033.         v1 = hitvertex(fx, fy);
  1034.         if (v1)
  1035.         UIstate = LPAR2STATE;
  1036.         break;
  1037.     case LPAR2STATE:
  1038.         l1 = hitline(fx, fy);
  1039.         if (l1) {
  1040.             if (sticky) UIstate = LPAR1STATE; else setselect();
  1041.         addprimitive(linevertlinepar(v1, l1));
  1042.         }
  1043.         break;
  1044.     case LCCEXT11:
  1045.         c1 = hitcircle(fx, fy);
  1046.         if (c1)
  1047.         UIstate = LCCEXT12;
  1048.         break;
  1049.     case LCCEXT12:
  1050.         c2 = hitanothercircle(fx, fy, c1);
  1051.         if (c2) {
  1052.             if (sticky) UIstate = LCCEXT11; else setselect();
  1053.         addprimitive(circcirctolineext1(c1, c2, fx, fy));
  1054.         }
  1055.         break;
  1056.     case LCCINT11:
  1057.         c1 = hitcircle(fx, fy);
  1058.         if (c1)
  1059.         UIstate = LCCINT12;
  1060.         break;
  1061.     case LCCINT12:
  1062.         c2 = hitanothercircle(fx, fy, c1);
  1063.         if (c2) {
  1064.             if (sticky) UIstate = LCCINT11; else setselect();
  1065.         addprimitive(circcirctolineint1(c1, c2, fx, fy));
  1066.         }
  1067.         break;
  1068.     case VCC11:
  1069.         c1 = hitcircle(fx, fy);
  1070.         if (c1)
  1071.         UIstate = VCC12;
  1072.         break;
  1073.     case VCC12:
  1074.         c2 = hitanothercircle(fx, fy, c1);
  1075.         if (c2) {
  1076.             if (sticky) UIstate = VCC11; else setselect();
  1077.         addprimitive(circcirctovert1(c1, c2, fx, fy));
  1078.         }
  1079.         break;
  1080.     case CVVV1:
  1081.         v1 = hitvertex(fx, fy);
  1082.         if (v1)
  1083.         UIstate = CVVV2;
  1084.         break;
  1085.     case CVVV2:
  1086.         v2 = hitvertex(fx, fy);
  1087.         if (v2)
  1088.         UIstate = CVVV3;
  1089.         break;
  1090.     case CVVV3:
  1091.         v3 = hitvertex(fx, fy);
  1092.         if (v3) {
  1093.             if (sticky) UIstate = CVVV1; else setselect();
  1094.         addprimitive(vvvtocircle(v1, v2, v3));
  1095.         }
  1096.         break;
  1097.     case C5V1:
  1098.         v1 = hitvertex(fx, fy);
  1099.         if (v1)
  1100.         UIstate = C5V2;
  1101.         break;
  1102.     case C5V2:
  1103.         v2 = hitvertex(fx, fy);
  1104.         if (v2 && (v2 != v1))
  1105.         UIstate = C5V3;
  1106.         break;
  1107.     case C5V3:
  1108.         v3 = hitvertex(fx, fy);
  1109.         if (v3 && (v3 != v2) && (v3 != v1))
  1110.         UIstate = C5V4;
  1111.         break;
  1112.     case C5V4:
  1113.         v4 = hitvertex(fx, fy);
  1114.         if (v4 && (v4 != v3) && (v4 != v2) && (v4 != v1))
  1115.         UIstate = C5V5;
  1116.         break;
  1117.     case C5V5:
  1118.         v5 = hitvertex(fx, fy);
  1119.         if (v5 && (v5 != v4) && (v5 != v3) && (v5 != v2) && (v5 != v1)) {
  1120.             if (sticky) UIstate = C5V1; else setselect();
  1121.         addprimitive(vvvvvtoconic(v1, v2, v3, v4, v5));
  1122.         }
  1123.         break;
  1124.     case SETCOLORS:
  1125.         p = hitprimitive(fx, fy);
  1126.         if (p) {
  1127.         if (sticky == 0) setselect();
  1128.         p->Color = currentcolor;
  1129.         }
  1130.         break;
  1131.     }
  1132.     unlocateall();
  1133. }
  1134.